home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / mui / mui-tools / multiuser / src / support / tasks.c < prev    next >
C/C++ Source or Header  |  1995-03-09  |  7KB  |  256 lines

  1. /************************************************************
  2. * MultiUser - MultiUser Task/File Support System                *
  3. * ---------------------------------------------------------    *
  4. * Get Information about Tasks                                            *
  5. * ---------------------------------------------------------    *
  6. * © Copyright 1993-1994 Geert Uytterhoeven                        *
  7. * All Rights Reserved.                                                    *
  8. ************************************************************/
  9.  
  10.  
  11. #include <exec/memory.h>
  12. #include <exec/execbase.h>
  13. #include <proto/exec.h>
  14. #include <proto/dos.h>
  15. #include <string.h>
  16. #include <libraries/multiuser.h>
  17. #include <proto/multiuser.h>
  18. #include <clib/alib_stdio_protos.h>
  19.  
  20. #include "Tasks_rev.h"
  21.  
  22. #include "Locale.h"
  23.  
  24. char __VersTag__[] = VERSTAG;
  25.  
  26.  
  27. struct TaskInfo {
  28.     struct Task *Task;
  29.     char Name[32];
  30.     ULONG TaskNum;
  31.     UBYTE Type;
  32.     BYTE Priority;
  33.     UWORD uid;
  34. };
  35.  
  36.  
  37. static ULONG CountTasks(struct ExecBase *SysBase);
  38. static BOOL FillTaskInfo(struct TaskInfo *tasks, ULONG maxtasks,
  39.                                  ULONG *numtasks, UWORD currentuid, BOOL all,
  40.                                  struct ExecBase *SysBase, struct muBase *muBase);
  41. static BOOL FillIt(struct Task *task, struct TaskInfo *info, UWORD currentuid,
  42.                          BOOL all, struct muBase *muBase);
  43. static ULONG DumpTaskInfo(struct TaskInfo *tasks, ULONG numtasks,
  44.                                   struct DosLibrary *DOSBase, struct muBase *muBase,
  45.                           struct LocaleInfo *li);
  46.  
  47.  
  48. int __saveds Start(char *arg)
  49. {
  50.     struct ExecBase *SysBase;
  51.     struct DosLibrary *DOSBase;
  52.     struct muBase *muBase = NULL;
  53.     struct RDArgs *args;
  54.     LONG argarray[] = {
  55.         NULL, NULL
  56.     };
  57.     UWORD currentuid;
  58.     struct TaskInfo *tasks;
  59.     ULONG maxtasks, numtasks;
  60.     struct muUserInfo *info;
  61.     LONG error = NULL;
  62.     int rc;
  63.     struct LocaleInfo li;
  64.  
  65.     SysBase = *(struct ExecBase **)4;
  66.     
  67.     if ((!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37))) ||
  68.          (!(muBase = (struct muBase *)OpenLibrary("multiuser.library", 39)))) {
  69.         rc = ERROR_INVALID_RESIDENT_LIBRARY;
  70.         goto Exit;
  71.     }
  72.  
  73.     OpenLoc(&li);
  74.  
  75.     args = ReadArgs("USERID,ALL/S", argarray, NULL);
  76.     if (!args)
  77.         error = IoErr();
  78.     else {
  79.         if (!argarray[0])
  80.             currentuid = muGetTaskOwner(NULL)>>16;
  81.         else if (info = muAllocUserInfo()) {
  82.             strncpy(info->UserID, (char *)argarray[0], muUSERIDSIZE-1);
  83.             info->UserID[muUSERIDSIZE-1] = '\0';
  84.             if (muGetUserInfo(info, muKeyType_UserID))
  85.                 currentuid = info->uid;
  86.             else {
  87.                 VPrintf(GetLocS(&li,MSG_UNKNOWN_USER), &argarray[0]);
  88.                 goto Fail;
  89.             }
  90.             muFreeUserInfo(info);
  91.         } else {
  92.             error = IoErr();
  93.             goto Fail;
  94.         }
  95.         do {
  96.             maxtasks = CountTasks(SysBase)+5;
  97.             if (tasks = AllocVec(maxtasks*sizeof(struct TaskInfo), MEMF_CLEAR)) {
  98.                 if (FillTaskInfo(tasks, maxtasks, &numtasks, currentuid,
  99.                                       (BOOL)argarray[1], SysBase, muBase)) {
  100.                     error = DumpTaskInfo(tasks, numtasks, DOSBase, muBase, &li);
  101.                     rc = RETURN_OK;
  102.                 } else
  103.                     rc = RETURN_ERROR;
  104.                 FreeVec(tasks);
  105.             } else
  106.                 error = IoErr();
  107.         } while (!error && (rc != RETURN_OK));
  108.     }
  109.     FreeArgs(args);
  110. Fail:
  111.     if (error) {
  112.         PrintFault(error, NULL);
  113.         rc = RETURN_ERROR;
  114.     }
  115.  
  116.     CloseLoc(&li);
  117.  
  118. Exit:
  119.     CloseLibrary((struct Library *)muBase);
  120.     CloseLibrary((struct Library *)DOSBase);
  121.  
  122.     return(rc);
  123. }    
  124.  
  125.  
  126.     /*
  127.      *        Count the number of tasks in the system
  128.      */
  129.  
  130. static ULONG CountTasks(struct ExecBase *SysBase)
  131. {
  132.     ULONG i = 1;
  133.     struct Task *task;
  134.  
  135.     Disable();
  136.     for (task = (struct Task *)SysBase->TaskReady.lh_Head;
  137.           task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
  138.           i++;
  139.     for (task = (struct Task *)SysBase->TaskWait.lh_Head;
  140.           task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
  141.           i++;
  142.     Enable();
  143.     return(i);
  144. }
  145.  
  146.  
  147.     /*
  148.      *        Fill in information about the tasks
  149.      */
  150.  
  151. static BOOL FillTaskInfo(struct TaskInfo *tasks, ULONG maxtasks,
  152.                                  ULONG *numtasks, UWORD currentuid, BOOL all,
  153.                                  struct ExecBase *SysBase, struct muBase *muBase)
  154. {
  155.     BOOL rc = TRUE;
  156.     struct Task *task;
  157.  
  158.     *numtasks = 0;
  159.     Disable();
  160.     if (FillIt(SysBase->ThisTask, &tasks[*numtasks], currentuid, all, muBase))
  161.         (*numtasks)++;
  162.     for (task = (struct Task *)SysBase->TaskReady.lh_Head;
  163.           (task->tc_Node.ln_Succ) && (*numtasks < maxtasks);
  164.           task = (struct Task *)task->tc_Node.ln_Succ)
  165.         if (FillIt(task, &tasks[*numtasks], currentuid, all, muBase))
  166.             (*numtasks)++;
  167.     if (task->tc_Node.ln_Succ)
  168.         rc = FALSE;
  169.     else {
  170.         for (task = (struct Task *)SysBase->TaskWait.lh_Head;
  171.               (task->tc_Node.ln_Succ) && (*numtasks < maxtasks);
  172.               task = (struct Task *)task->tc_Node.ln_Succ)
  173.             if (FillIt(task, &tasks[*numtasks], currentuid, all, muBase))
  174.                 (*numtasks)++;
  175.         if (task->tc_Node.ln_Succ)
  176.             rc = FALSE;
  177.     }
  178.     Enable();
  179.     return(rc);
  180. }
  181.  
  182.  
  183. static BOOL FillIt(struct Task *task, struct TaskInfo *info, UWORD currentuid,
  184.                          BOOL all, struct muBase *muBase)
  185. {
  186.     UWORD uid;
  187.     struct CommandLineInterface *cli;
  188.     char *name;
  189.     ULONG i;
  190.  
  191.     uid = muGetTaskOwner(task)>>16;
  192.     if (all || (uid == currentuid)) {
  193.         info->Task = task;
  194.         if (((info->Type = task->tc_Node.ln_Type) == NT_PROCESS) &&
  195.              (info->TaskNum = ((struct Process *)task)->pr_TaskNum) &&
  196.              (cli = (struct CommandLineInterface *)BADDR(((struct Process *)task)->pr_CLI)) &&
  197.              (name = BADDR(cli->cli_CommandName)) && name[0]) {
  198.             for (i = 0; (i < name[0]) && (i < 31); i++)
  199.                 info->Name[i] = name[i+1];
  200.             info->Name[i] = '\0';
  201.         } else {
  202.             strncpy(info->Name, task->tc_Node.ln_Name, 31);
  203.             info->Name[31] = '\0';
  204.         }
  205.         info->Priority = task->tc_Node.ln_Pri;
  206.         info->uid = uid;
  207.         return(TRUE);
  208.     } else
  209.         return(FALSE);
  210. }
  211.  
  212.  
  213.     /*
  214.      *        Dump the information
  215.      */
  216.  
  217. static ULONG DumpTaskInfo(struct TaskInfo *tasks, ULONG numtasks,
  218.                                   struct DosLibrary *DOSBase, struct muBase *muBase,
  219.                           struct LocaleInfo *li)
  220. {
  221.     struct muUserInfo *info;
  222.     ULONG error = NULL;
  223.     ULONG i;
  224.     LONG stream[5];
  225.     UBYTE typebuff[40]; /* should be enough ! */
  226.  
  227.     if (info = muAllocUserInfo()) {
  228.         PutStr(GetLocS(li,MSG_TFORMAT_HEAD1));
  229.         PutStr(GetLocS(li,MSG_TFORMAT_HEAD2));
  230.          for (i= 0; (i < numtasks) && !CheckSignal(SIGBREAKF_CTRL_C); i++) {
  231.              if (tasks[i].Type == NT_PROCESS)
  232.                  if (tasks[i].TaskNum) {
  233.                      sprintf(typebuff,GetLocS(li,MSG_CLI), tasks[i].TaskNum);
  234.                     stream[0] = (LONG)typebuff;
  235.                 }
  236.                  else
  237.                      stream[0] = (LONG)GetLocS(li,MSG_PROC);
  238.             else
  239.                 stream[0] = (LONG)GetLocS(li,MSG_TASK);
  240.              stream[1] = (LONG)tasks[i].Task;
  241.              stream[2] = (LONG)tasks[i].Priority;
  242.              stream[3] = (LONG)tasks[i].Name;
  243.             if ((info->uid = tasks[i].uid) == muOWNER_NOBODY)
  244.                 stream[4] = (LONG)"";
  245.             else if (muGetUserInfo(info, muKeyType_uid))
  246.                 stream[4] = (LONG)info->UserID;
  247.             else
  248.                 stream[4] = (LONG)"???";
  249.             VPrintf(GetLocS(li,MSG_TFORMAT_LINE), stream);
  250.         }
  251.         muFreeUserInfo(info);
  252.     } else
  253.         error = IoErr();
  254.     return(error);
  255. }
  256.